package com.ppc.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.ppc.constant.MessageConstant;
import com.ppc.constant.PictureConstant;
import com.ppc.context.BaseContext;
import com.ppc.dto.UserLoginVerifyCodeDTO;
import com.ppc.dto.WorkerChangeInfoDTO;
import com.ppc.dto.WorkerLoginDTO;
import com.ppc.entity.File;
import com.ppc.entity.Recording;
import com.ppc.entity.Tag;
import com.ppc.entity.UserPPC;
import com.ppc.exception.AccountNotFoundException;
import com.ppc.exception.BaseException;
import com.ppc.exception.FileException;
import com.ppc.exception.PasswordErrorException;
import com.ppc.mapper.user.FileMapper;
import com.ppc.mapper.user.UserMapper;
import com.ppc.mapper.worker.WorkerMapper;
import com.ppc.result.PageResult;
import com.ppc.result.Result;
import com.ppc.service.WorkerService;
import com.ppc.utils.MinIoUtil;
import com.ppc.utils.StringUtil;
import com.ppc.vo.WorkerCreditVO;
import com.ppc.vo.WorkerInfoQueryVO;
import com.ppc.vo.WorkerLoginVO;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * 工人接口实现
 *
 * @author Jeferry
 * @date 2023/12/20
 */
@Service
public class WorkerServiceImpl implements WorkerService {

  @Autowired
  private WorkerMapper workerMapper;
  @Autowired
  private MinIoUtil minIoUtil;

  @Autowired
  private FileMapper fileMapper;

  @Autowired
  private UserMapper userMapper;

  /**
   * 工人登录
   *
   * @param workerLoginDTO 工人登录信息
   * @return {@link WorkerLoginVO}
   */
  @Override
  public WorkerLoginVO login(WorkerLoginDTO workerLoginDTO) {
    String userphone = workerLoginDTO.getUserPhone();
    String userEmail = workerLoginDTO.getUserEmail();
    String userPassword = workerLoginDTO.getUserPassword();
    //对密码进行md5加密
    userPassword = DigestUtils.md5DigestAsHex(userPassword.getBytes());
    UserPPC user = UserPPC.builder()
        .userEmail(userEmail)
        .userPhone(userphone)
        .build();
    //1、根据工人的手机号查询数据库中的数据
    WorkerLoginVO worker = workerMapper.getWorkerByphoneOrEmail(user);
    if (worker == null) {
      throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
    }
    String realPassword = workerMapper.getPasswordByphoneOrEmail(user);
    //2、处理各种异常情况（用户名不存在、密码不对,用户状态锁定等等）

    if (worker.getWorkerStatus() == 0) {
      throw new BaseException(MessageConstant.ACCOUNT_LOCKED);
    }
    if (worker.getWorkerStatus() == 2) {
      throw new BaseException(MessageConstant.ACCOUNT_IS_CANCEL);
    }

    //密码比对
    if (!userPassword.equals(realPassword)) {
      //密码错误
      throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
    }
    //利用工具类，获取file的下载路径
    worker.setFileUrl(minIoUtil.getFileUrl(worker.getFileUrl()));
    return worker;
  }

  @Override
  public WorkerLoginVO loginVerfiy(UserLoginVerifyCodeDTO userLoginVerifyCodeDTO) {
    String userphone = userLoginVerifyCodeDTO.getUserPhone();
    String userEmail = userLoginVerifyCodeDTO.getUserEmail();
    //对密码进行md5加密
   UserPPC user = UserPPC.builder()
        .userEmail(userEmail)
        .userPhone(userphone)
        .build();
    //1、根据工人的手机号查询数据库中的数据
    WorkerLoginVO worker = workerMapper.getWorkerByphoneOrEmail(user);
    if (worker == null) {
      throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
    }

    if (worker.getWorkerStatus() == 0) {
      throw new BaseException(MessageConstant.ACCOUNT_LOCKED);
    }
    if (worker.getWorkerStatus() == 2) {
      throw new BaseException(MessageConstant.ACCOUNT_IS_CANCEL);
    }

    //利用工具类，获取file的下载路径
    worker.setFileUrl(minIoUtil.getFileUrl(worker.getFileUrl()));
    return worker;

  }

  /**
   * 查询工人的信誉
   *
   * @param workerid 工人的id
   * @return {@link List}<{@link WorkerCreditVO}>
   */
  @Override
  public List<WorkerCreditVO> checkCredit(Integer workerid) {
    //调用mapper层来进行查询
    List<WorkerCreditVO> workers = workerMapper.checkCreditById(workerid);
    if (workers == null) {
      throw new BaseException("工人暂未参加任何任务");
    }
    return workers;
  }

  /**
   * 查询工人的个人信息
   *
   * @param workerid 工人的id
   * @return {@link WorkerInfoQueryVO}
   */
  @Override
  public WorkerInfoQueryVO queryInformation(Integer workerid) {
    WorkerInfoQueryVO worker = workerMapper.queryInformationById(workerid);
    //因该没有异常要抛出，最多就是worker不存在，但是是登陆后查看个人信息，不存在这种情况
    //利用工具类，获取file的下载路径
    worker.setFileUrl(minIoUtil.getFileUrl(worker.getFileUrl()));
    return worker;
  }

  /**
   * 修改工人的个人信息
   *
   * @param workerChangeInfoDTO 工人的个人信息
   */
  @Override
  public void changeInformation(WorkerChangeInfoDTO workerChangeInfoDTO) {
    Long userId = BaseContext.getCurrentId();
    UserPPC userPPC = UserPPC.builder()
        .userId(userId)
        .userName(workerChangeInfoDTO.getUserName())
        .userEmail(workerChangeInfoDTO.getUserEmail())
        .userPhone(workerChangeInfoDTO.getUserPhone())
        .userPassword(workerChangeInfoDTO.getUserPassword())
        .fileId(workerChangeInfoDTO.getFileId())
        .gender(workerChangeInfoDTO.getGender())
        .birthday(workerChangeInfoDTO.getBirthday())
        .build();
    if(workerChangeInfoDTO.getUserPassword()!=null&&workerChangeInfoDTO.getUserPassword()!="")
    {
      userPPC.setUserPassword(DigestUtils.md5DigestAsHex(workerChangeInfoDTO.getUserPassword().getBytes()));
    }
    if((userPPC.getUserPhone()!=null && userPPC.getUserPhone()!= "")||(userPPC.getUserEmail()!=null && userPPC.getUserEmail()!= ""))
    {
      List<UserPPC> userPPCList = userMapper.getUserByPhoneOrEmail(userPPC.getUserPhone(), userPPC.getUserEmail());
      if(userPPCList.size()>0)
      {
        throw new BaseException("该邮箱或手机号已被注册");
      }
    }
    workerMapper.changeInformationInppc(userPPC);
  }

  /**
   * 修改工人的标签
   *
   * @param tagNameList 工人的标签列表
   */
  @Override
  public void changeTag(List<Integer> tagNameList) {
    String tags = "";
    for (int i = 0; i < tagNameList.size(); i++) {
      if (i < tagNameList.size() - 1) {
        tags += tagNameList.get(i) + ",";
      } else {
        tags += tagNameList.get(i);
      }
    }
    Long currentId = BaseContext.getCurrentId();
    workerMapper.changeWorkerTag(currentId, tags);
  }

  /**
   * 增加工人的标签
   *
   * @param tagId 标签id
   */
  @Override
  public void addTag(Integer tagId) {
    Long userId = BaseContext.getCurrentId();
    Long currentWorkerId = workerMapper.getCurrentWorkerId(userId);
    //获取相应的标签Id
    String tags = workerMapper.queryTagsById(currentWorkerId);
    //存到string数组中
    String[] tagArray = tags.split(",");
    for (int i = 0; i < tagArray.length; i++) {
      if (tagArray[i].equals(String.valueOf(tagId))) {
        throw new BaseException("工人已存在相应标签");
      }
    }
    tags += "," + tagId;
    String newtags = StringUtil.sortAndCombine(tags);
    workerMapper.changeWorkerTag(userId, newtags);
  }

  /**
   * 删除工人的标签
   *
   * @param tagId 标签id
   */
  @Override
  public void deleteTag(Integer tagId) {
    Long userId = BaseContext.getCurrentId();
    Long currentWorkerId = workerMapper.getCurrentWorkerId(userId);
    //获取相应的标签Id
    String tags = workerMapper.queryTagsById(currentWorkerId);
    //存到string数组中
    String[] tagArray = tags.split(",");
    boolean flag = false;
    for (int i = 0; i < tagArray.length; i++) {
      if (tagArray[i].equals(String.valueOf(tagId))) {
        flag = true;
      }
    }
    if (flag == false) {
      throw new BaseException("工人不存在对应标签");
    }
    int[] numbersToRemove = {tagId};
    String newtags = StringUtil.sortAndRemove(tags, numbersToRemove);
    workerMapper.changeWorkerTag(userId, newtags);
  }

  /**
   * 工人展示自己标签
   *
   * @param page 页码
   * @param pageSize 页大小
   * @return {@link Result}<{@link PageResult}>
   */
  @Override
  public PageResult showMyTags(Integer page, Integer pageSize) {
    Long userId = BaseContext.getCurrentId();
    Long currentWorkerId = workerMapper.getCurrentWorkerId(userId);
    //先获取工人的标签
    String tags = workerMapper.queryTagsById(currentWorkerId);
    //再去tag表中寻找对应标签信息
    String[] tagArray = tags.split(",");
    List<Integer> workerTags = new ArrayList<>();
    for (int i = 0; i < tagArray.length; i++) {
      workerTags.add(Integer.valueOf(tagArray[i]));
    }
    PageHelper.startPage(page, pageSize);
    Page<Tag> p  = workerMapper.selectTags(workerTags);
    return new PageResult(p.getTotal(), p.getResult());
  }

  /**
   * 展示所有标签
   *
   * @param page     页码
   * @param pageSize 页大小
   * @return {@link PageResult}
   */
  @Override
  public PageResult selectAllTags(Integer page, Integer pageSize) {
    PageHelper.startPage(page, pageSize);
    Page<Tag> p = workerMapper.TagsQuery();
    return new PageResult(p.getTotal(), p.getResult());
  }

  /**
   * 展示所有有关信誉的日志
   *
   * @return {@link List}<{@link String}>
   */
  @Override
  public List<String> showRecordingCredit() {
    Long userId = BaseContext.getCurrentId();
    List<String> list = workerMapper.selectRecordingCredit(userId);
    return list;
  }

  /**
   * 展示所有有关金钱的日志
   *
   * @return {@link List}<{@link String}>
   */
  @Override
  public List<String> showRecordingMoney() {
    Long userId = BaseContext.getCurrentId();
    List<String> list = workerMapper.selectRecordingMoney(userId);
    return list;
  }

  /**
   * 注销账户
   */
  @Override
  public void logOffAccount() {
    Long userId = BaseContext.getCurrentId();
    Long currentWorkerId = workerMapper.getCurrentWorkerId(userId);
    //如果有工人还在参与的任务,那么就强制他不可以注销账号
    if (workerMapper.selectWorkerCount(currentWorkerId) > 0) {
      throw new BaseException("工人还有任务未完成,不可以注销");
    }
    //先修改一下工人的状态
    workerMapper.logOffAccount(currentWorkerId);
    //将userppc里的账号手机和邮箱清空来后面有人可以重新注册
    UserPPC userPPC = UserPPC.builder().
        userId(userId).
        userPhone("***").
        userEmail("***").
        build();
    workerMapper.changeInformationInppc(userPPC);
  }

  /**
   * 工人提现
   *
   * @param money 提现金额
   */
  @Override
  public void cashWithdrawal(Float money) {
    //修改工人的余额
    Long userId = BaseContext.getCurrentId();
    Long currentWorkerId = workerMapper.getCurrentWorkerId(userId);
    //先获取当前工人的余额
    WorkerInfoQueryVO workerInfoQueryVO = workerMapper.queryInformationById(
        Math.toIntExact(currentWorkerId));
    float workerCount = workerInfoQueryVO.getWorkerCount();
    //进行修改
    workerCount = workerCount - money;
    if (workerCount < 0) {
      throw new BaseException("提现金额过大,余额不足,请重新输入");
    }
    workerMapper.cashWithdrawal(currentWorkerId, workerCount);
    //向recording表中插入对应记录、
    // 获取当前时间
    LocalDateTime now = LocalDateTime.now();
    // 定义日期时间格式
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    // 格式化LocalDateTime对象
    String formattedDateTime = now.format(formatter);
    String content = formattedDateTime + " 提现了" + money + "元," + "钱包余额-" + money + "元";
    Recording recording = Recording.builder()
        .userId(userId)
        .recordingContent(content)
        .recordingType(0)
        .build();
    workerMapper.insertIntoRecording(recording);
  }

  @Override

  public Long uploadImg(MultipartFile file) {

    String originalFilename = file.getOriginalFilename();
    int lastIndexOf = originalFilename.lastIndexOf(".");
    String extension = originalFilename.substring(lastIndexOf + 1);

    if (!PictureConstant.SUPPORT_PICTURE.contains(extension)) {
      throw new FileException(MessageConstant.UNSUPPORT_FILE_TYPE + extension);
    } else {

      String objectName = minIoUtil.updateFileName(originalFilename);
      String filepath = minIoUtil.getFileUrl(objectName);

      try {
        minIoUtil.upload(objectName, file);
        //在file表添加一条
        File imgFile = File.builder()
            .fileName(originalFilename)
            .fileUrl(objectName)
            .fileType(extension)
            .build();

        fileMapper.insertFile(imgFile);
        workerMapper.updateImg(imgFile.getFileId(), BaseContext.getCurrentId());
        return imgFile.getFileId();
      } catch (Exception e) {
        throw new FileException(MessageConstant.UPLOAD_FAILED);
      }
    }


  }


}
